package com.jxs.easysecurity.http;

import com.jxs.easysecurity.resource.http.UriResource;
import com.jxs.easysecurity.resource.http.UriResourceDataSource;
import com.jxs.easysecurity.session.Session;
import com.jxs.easysecurity.session.SessionManager;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author jiangxingshang
 * @since 17/6/22
 */
public class SecurityValidationFilter implements Filter {

    private SessionManager sessionManager;
    private UriResourceDataSource dataSource;


    private HttpSecurityService securityService;

    public SecurityValidationFilter(SessionManager sessionManager, UriResourceDataSource dataSource) {
        this.sessionManager = sessionManager;
        this.dataSource = dataSource;
        securityService = new HttpSecurityService(sessionManager);
    }

    //可选的拦截器
    private SecurityFilterInterceptor interceptor;
    public SecurityValidationFilter setInterceptor(SecurityFilterInterceptor interceptor) {
        this.interceptor = interceptor;
        return this;
    }

    //安全验证失败监听器
    private SecurityValidationListener securityValidationListener;
    public void setOnSecurityValidationFail(SecurityValidationListener securityValidationListener) {
        this.securityValidationListener = securityValidationListener;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse resp = (HttpServletResponse)response;
        String uri = req.getRequestURI();

        Session session = sessionManager.getSession();

        //请求入口拦截器
        if(interceptor != null) {
            if(!interceptor.onPreHandle(req, resp, chain, session)) {
                return;
            }
        }

        UriResource res = dataSource.match(uri, req.getMethod());

        //找到匹配的资源后，交给拦截器
        if(interceptor != null) {
            if(!interceptor.onResourceFound(req, resp, chain, res, session)) {
                return;
            }
        }

        //安全验证
        HttpSecurityService.ValidationResult result = securityService.validate(session, res);

        //处理验证结果
        if(result == HttpSecurityService.ValidationResult.IGNORE || result == HttpSecurityService.ValidationResult.SUCCESS) {
            chain.doFilter(req, resp);
        } else {
            if(securityValidationListener != null) {
                securityValidationListener.onFail(req, resp, result);
            } else {
                resp.setStatus(401);
            }
        }
    }

    @Override
    public void destroy() {

    }
}
